package com.apps.datastore;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.List;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.QueryResultIterator;
import com.google.appengine.api.datastore.Transaction;
import com.google.appengine.api.datastore.Query.FilterOperator;

public class NoSignupDatastore {
	
	public static final String DATASTORE_ENTITY_SET_NAME= "No Sign Up Notifier Set";
	public static final String DATASTORE_ENTITY_KEY_NAME= "NO_SIGN_UP_DATA";
	
	public static final String ENTRY_KIND = "Entry";
	
	//Account property name
	public static final String EMAIL_PROPERTY= "Email";
	public static final String ACTIVATED_PROPERTY = "Activated";
	public static final String VERIFY_KEY_PROPERTY="Verify Key";
	public static final String PHONE_NUMBER_PROPERTY= "Phone Number";
	
	public static final String DEPT_PROPERTY= "Dept";
	public static final String COURSE_PROPERTY= "Course";
	public static final String SECTION_PROPERTY= "Section";
	
	private static DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
	
	public NoSignupDatastore(){
		initSchema();
	}
	
	private static void initSchema(){
		Query q = new Query(DATASTORE_ENTITY_SET_NAME);
		q.setKeysOnly();
		if(datastore.prepare(q).asSingleEntity() == null) {
			Transaction txn = datastore.beginTransaction();    
			Entity e = new Entity(DATASTORE_ENTITY_SET_NAME, DATASTORE_ENTITY_KEY_NAME);
			datastore.put(e);
			txn.commit();
		}
	}
	
	public static String addNotifier(String email, String pNum, String dept, String course, String section){
		String verifyKey = generateVerificationKey();
		Key k = KeyFactory.createKey(DATASTORE_ENTITY_SET_NAME, DATASTORE_ENTITY_KEY_NAME); 
		Transaction txn = datastore.beginTransaction();                                
		Entity e = new Entity(ENTRY_KIND,k);                                       
		e.setProperty(EMAIL_PROPERTY, email);     
		e.setProperty(ACTIVATED_PROPERTY, false);
		e.setProperty(VERIFY_KEY_PROPERTY, verifyKey);
		e.setProperty(PHONE_NUMBER_PROPERTY, pNum);
		e.setProperty(DEPT_PROPERTY, dept);
		e.setProperty(COURSE_PROPERTY, course);
		e.setProperty(SECTION_PROPERTY, section);
		datastore.put(e);                                                              
		txn.commit();
		return verifyKey;
	}
	
	private static String generateVerificationKey(){
		MessageDigest m;
		try {
			m = MessageDigest.getInstance("MD5");
			StringBuilder sb = new StringBuilder();
			sb.append(System.nanoTime());
			String randomString = sb.toString();
			m.update(randomString.getBytes(), 0, randomString.length());
			return new BigInteger(1,m.digest()).toString(16);

		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}
	
	public static boolean verify(String key){
		Query q = new Query(ENTRY_KIND);
		q.addFilter(VERIFY_KEY_PROPERTY, FilterOperator.EQUAL, key);
		q.addFilter(ACTIVATED_PROPERTY, FilterOperator.EQUAL, false);
		PreparedQuery pq = datastore.prepare(q);
			try {
				Entity e = pq.asSingleEntity();
				if(e != null ) {
					e.setProperty(ACTIVATED_PROPERTY, true);
					datastore.put(e);
					return true;
				}
			}
			catch (Exception e){
				return false;
			}
		return false;
	}
	
	public static void deleteNotifier(String email, String pNum, String dept, String course, String section){
		Query q = new Query(ENTRY_KIND);
		q.setKeysOnly();
		q.addFilter(EMAIL_PROPERTY, FilterOperator.EQUAL, email);
		q.addFilter(DEPT_PROPERTY, FilterOperator.EQUAL, dept);
		q.addFilter(COURSE_PROPERTY, FilterOperator.EQUAL, course);
		q.addFilter(SECTION_PROPERTY, FilterOperator.EQUAL, section);
		PreparedQuery pq = datastore.prepare(q);
		Iterator<Entity> it = pq.asIterable().iterator();
		while(it.hasNext())
			datastore.delete(it.next().getKey());
		
	}
	
	public static QueryResultIterator<Entity> getAll(){
		Query q = new Query(ENTRY_KIND);
		PreparedQuery pq = datastore.prepare(q);
		return pq.asQueryResultIterator();
	}
	
	
	

}
